using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Supremacy.Client.Controls
{
    internal sealed class GamePopupRoot : FrameworkElement
    {
        private AdornerDecorator _adornerDecorator;
        private Decorator _transformDecorator;

        static GamePopupRoot()
        {
            SnapsToDevicePixelsProperty.OverrideMetadata(typeof(GamePopupRoot), new FrameworkPropertyMetadata(true));
        }

        internal GamePopupRoot()
        {
            this.Initialize();
        }

        protected override Size ArrangeOverride(Size arrangeSize)
        {
            _transformDecorator.Arrange(new Rect(arrangeSize));
            return arrangeSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            return _transformDecorator;
        }

        private void Initialize()
        {
            _transformDecorator = new Decorator();
            base.AddVisualChild(_transformDecorator);
            _transformDecorator.ClipToBounds = true;
            _adornerDecorator = new NonLogicalAdornerDecorator();
            _transformDecorator.Child = _adornerDecorator;
        }

        protected override Size MeasureOverride(Size constraint)
        {
            _transformDecorator.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            var desiredSize = _transformDecorator.DesiredSize;
            //var parent = base.Parent as GamePopup;
            //if (parent != null)
            //{
            //    Size size2 = parent.RestrictSize(desiredSize);
            //    if ((Math.Abs((double)(size2.Width - desiredSize.Width)) <= 0.01) &&
            //        (Math.Abs((double)(size2.Height - desiredSize.Height)) <= 0.01))
            //    {
            //        return desiredSize;
            //    }
            //    desiredSize = size2;
            //    _transformDecorator.Measure(desiredSize);
            //}
            return desiredSize;
        }

        internal void SetupFadeAnimation(Duration duration, bool visible)
        {
            var animation = new DoubleAnimation(
                visible ? 0.0 : 1.0,
                visible ? 1.0 : 0.0,
                duration,
                FillBehavior.HoldEnd);
            base.BeginAnimation(OpacityProperty, animation);
        }

        internal void SetupLayoutBindings(Popup popup)
        {
            _adornerDecorator.SetBinding(
                WidthProperty,
                new Binding("Width")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });

            _adornerDecorator.SetBinding(
                HeightProperty,
                new Binding("Height")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });

            _adornerDecorator.SetBinding(
                MinWidthProperty,
                new Binding("MinWidth")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });

            _adornerDecorator.SetBinding(
                MinHeightProperty,
                new Binding("MinHeight")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });

            _adornerDecorator.SetBinding(
                MaxWidthProperty,
                new Binding("MaxWidth")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });

            _adornerDecorator.SetBinding(
                MaxHeightProperty,
                new Binding("MaxHeight")
                {
                    Mode = BindingMode.OneWay,
                    Source = popup
                });
        }

        internal void SetupTranslateAnimations(PopupAnimation animationType, Duration duration, bool animateFromRight, bool animateFromBottom)
        {
            var child = this.Child;
            if (child == null)
                return;

            var renderTransform = _adornerDecorator.RenderTransform as TranslateTransform;
            if (renderTransform == null)
            {
                renderTransform = new TranslateTransform();
                _adornerDecorator.RenderTransform = renderTransform;
            }

            if (animationType == PopupAnimation.Scroll)
            {
                var direction = (FlowDirection)child.GetValue(FlowDirectionProperty);
                var flowDirection = base.FlowDirection;
                
                if (direction != flowDirection)
                    animateFromRight = !animateFromRight;

                var width = _adornerDecorator.RenderSize.Width;
                var horizontalAnimation = new DoubleAnimation(
                    animateFromRight ? width : -width,
                    0.0,
                    duration,
                    FillBehavior.Stop);
                
                renderTransform.BeginAnimation(TranslateTransform.XProperty, horizontalAnimation);
            }

            var height = _adornerDecorator.RenderSize.Height;
            var verticalAnimation = new DoubleAnimation(
                animateFromBottom ? height : -height,
                0.0,
                duration,
                FillBehavior.Stop);

            renderTransform.BeginAnimation(TranslateTransform.YProperty, verticalAnimation);
        }

        internal void StopAnimations()
        {
            base.BeginAnimation(OpacityProperty, null);
            
            var renderTransform = _adornerDecorator.RenderTransform as TranslateTransform;
            if (renderTransform == null)
                return;

            renderTransform.BeginAnimation(TranslateTransform.XProperty, null);
            renderTransform.BeginAnimation(TranslateTransform.YProperty, null);
        }

        internal Vector AnimationOffset
        {
            get
            {
                var renderTransform = _adornerDecorator.RenderTransform as TranslateTransform;
                if (renderTransform != null)
                    return new Vector(renderTransform.X, renderTransform.Y);
                return new Vector();
            }
        }

        internal UIElement Child
        {
            get { return _adornerDecorator.Child; }
            set { _adornerDecorator.Child = value; }
        }

        internal Transform Transform
        {
            set { _transformDecorator.LayoutTransform = value; }
        }

        protected override int VisualChildrenCount
        {
            get { return 1; }
        }
    }
}